home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 09 - 1993 / 09.04 Apr 93 / Creating EPSF Files / DrawEPSF.c next >
Encoding:
C/C++ Source or Header  |  1992-07-15  |  5.6 KB  |  177 lines  |  [TEXT/KAHL]

  1. /* DrawEPSF.c */
  2. /* Copyright 1992, Gary D. McGath */
  3.  
  4. extern void InitOutBuf(void);
  5. extern void OutputString(char *str, int theFile);
  6. extern void OutputChar(int ch,int theFile);
  7. extern void OutputNum(int n, int theFile);
  8. extern void FlushOutBuf(int theFile);
  9.  
  10. OSErr CreateEPSFFile(SFReply *theReply, int *theFile);
  11. void DrawEPSF(PicHandle han, int theFile);
  12. void WriteBoundingBox(PicHandle han,Rect *bbRect, int theFile);
  13. void WritePrologue(int theFile);
  14. void FlipCoords(Rect *RectP, int theFile);
  15. void WriteEpilogue(int theFile);
  16.  
  17.  
  18. /* The strings of the prologue. To conserve data space, these could
  19.    be put into a resource. */
  20. char *prologueStrs[] = {
  21. "/_E_save save def\r",
  22. "/our_dict 70 dict def\r",
  23. "our_dict begin /bd {bind def} def  /xd {exch def} bd\r",
  24. "/rdims {/bt xd /rt xd /tp xd /lf xd} bd\r",
  25. "/fradj {/tp tp phw add def /bt bt phw sub def\r",
  26. "  /lf lf phw add def /rt rt phw sub def} bd\r",
  27. "/arctopppp {arcto pop pop pop pop} bd\r",
  28.  
  29.     /* fill rect proc: l t r b flrec */
  30. "/flrec {rdims lf tp moveto rt tp lineto rt bt lineto lf bt lineto closepath fill} bd\r",
  31.  
  32.     /* frame rect proc: l t r b pen.h pen.v frrec */
  33. "/frrec {/pnh xd /pnw xd rdims\r",
  34. "  lf tp moveto rt tp lineto rt bt lineto lf bt lineto closepath\r",
  35. "  /lf lf pnw add def /tp tp pnh add def /rt rt pnw sub def /bt bt pnh sub def\r",
  36. "  lf tp moveto rt tp lineto rt bt lineto lf bt lineto closepath\r",
  37. " eofill} bd\r",
  38.  
  39.     /* fill oval proc: l t r b floval */
  40. "/floval {rdims gsave lf rt add 2 div tp bt add 2 div translate\r",
  41. " rt lf sub 2 div bt tp sub 2 div scale\r",
  42. " 1 0 moveto 0 0 1 0 360 arc fill grestore} bd\r",
  43.  
  44.     /* frame oval proc: l t r b pen.h froval */
  45. "/froval {dup /pnw xd setlinewidth",
  46. "/phw pnw 0.5 mul def fradj",
  47. "  rdims /mt matrix currentmatrix def lf rt add 2 div tp bt add 2 div translate\r",
  48. "  rt lf sub 2 div bt tp sub 2 div scale\r",
  49. "  1 0 moveto 0 0 1 0 360 arc mt setmatrix stroke} bd\r",
  50.  
  51.     /* frame arc proc: l t r b pen.h startangle arcangle frarc */
  52. "/frarc {/arca xd /stra xd setlinewidth rdims\r",
  53. "  /mt matrix currentmatrix def lf rt add 2 div tp bt add 2 div translate\r",
  54. "  rt lf sub 2 div bt tp sub 2 div scale\r",
  55. "  0 0 1 stra 90 sub dup arca add arc mt setmatrix stroke} bd\r",
  56.  
  57. "/flarc {/arca xd /stra xd rdims\r",
  58. "  gsave lf rt add 2 div tp bt add 2 div translate\r",
  59. "  rt lf sub 2 div bt tp sub 2 div scale\r",
  60. "  0 0 moveto 0 0 1 stra 90 sub dup arca add arc fill grestore} bd\r",
  61.  
  62.     /* frame round rect proc: l t r b pen.h rad.h
  63.        This version makes the simplifying assumptions of a square pen and
  64.        circular (not elliptical) corners. */
  65. "/frrrect {/rd xd /pnw xd rdims /phw pnw 0.5 mul def fradj\r",
  66. "  rt rd sub tp moveto rt tp rt tp rd add rd arctopppp\r",
  67. "  rt bt rt rd sub bt rd arctopppp\r",
  68. "  lf bt lf bt rd sub rd arctopppp\r",
  69. "  lf tp lf rd add tp rd arctopppp\r closepath stroke} bd\r",
  70.  
  71.     /* fill round rect: l t r b rad.h */
  72. "/flrrect {/rd xd rdims\r",
  73. "  rt rd sub tp moveto rt tp rt tp rd add rd arctopppp\r",
  74. "  rt bt rt rd sub bt rd arctopppp\r",
  75. "  lf bt lf bt rd sub rd arctopppp\r",
  76. "  lf tp lf rd add tp rd arctopppp\r closepath fill} bd\r",
  77. ""                            /* last string must be null */
  78. };
  79.  
  80. char *epilogueStrs[] = {
  81. "end _E_save restore\r",
  82. ""
  83. };
  84.  
  85. int thePSResFile;
  86.  
  87.  
  88. /* Call this before calling DrawEPSF. */
  89. OSErr CreateEPSFFile(SFReply *theReply, int *theFile)
  90.     {
  91.     OSErr err;
  92.     FSDelete(&theReply->fName[0],theReply->vRefNum);    /* delete any old file */
  93.     err = Create(&theReply->fName[0], theReply->vRefNum, '????', 'EPSF');
  94.     err = FSOpen(&theReply->fName[0], theReply->vRefNum, theFile);
  95.     SetVol((StringPtr) 0, theReply->vRefNum);
  96.     CreateResFile(&theReply->fName[0]);
  97.     thePSResFile = OpenResFile(&theReply->fName[0]);
  98.     if (err != noErr)
  99.         *theFile = 0;
  100.     return err;
  101.     }
  102.  
  103. /* The main routine for writing the data fork of the EPSF file. */
  104. void DrawEPSF(PicHandle han, int theFile)
  105.     {
  106.     GrafPtr savePort;
  107.     GrafPtr dstPort;
  108.     Rect dstRect;
  109.     Rect *picRectPtr;
  110.     InitOutBuf();
  111.     OutputString("%!PS-Adobe-3.0 EPSF-3.0\r", theFile);    /* doesn't really belong here */
  112.     picRectPtr = &(**han).picFrame;
  113.     dstRect.left = 0;
  114.     dstRect.top = 0;
  115.     dstRect.right = picRectPtr->right;
  116.     dstRect.bottom = picRectPtr->bottom;
  117.     WriteBoundingBox(han, &dstRect,theFile);
  118.     WritePrologue(theFile);
  119.     FlipCoords(&dstRect, theFile);
  120.     GetPort(&savePort);
  121.     dstPort = (GrafPtr) NewPtr(sizeof(GrafPort));
  122.     if (dstPort == 0)
  123.         return;
  124.     OpenPort(dstPort);
  125.     psdInitPort(dstPort);
  126.     psdSetupProcs(dstPort);            /* set up port and bottleneck procs */
  127.     SetPort((GrafPtr)dstPort);
  128.     DrawPicture(han,picRectPtr);
  129.  
  130.     WriteEpilogue(theFile);
  131.     FlushOutBuf(theFile);
  132.     SetPort(savePort);            /* go back to original port */
  133.     ClosePort(dstPort);
  134.     DisposPtr(dstPort);
  135.     }
  136.  
  137. /* Get the dimensions of the PICT, and write them as a BoundingBox
  138.    comment */
  139. void WriteBoundingBox(PicHandle han, Rect *RectP, int theFile)
  140. {
  141.     OutputString("%%BoundingBox: 0 0 ", theFile);
  142.     OutputNum(RectP->right, theFile);
  143.     OutputNum(RectP->bottom, theFile);
  144.     OutputChar('\r',theFile);
  145. }
  146.  
  147. /* Write out the prologue code of the file. For a real application, this
  148.    should be gotten out of a resource file so it doesn't use up string space. */
  149. void WritePrologue(int theFile)
  150. {
  151.     register int i;
  152.     for (i=0;; i++) {
  153.         if (prologueStrs[i][0] == 0)        /* finished? */
  154.             break;
  155.         OutputString(prologueStrs[i], theFile);
  156.     }    
  157. }
  158.  
  159. /* Flip the coordinate system so it matches the QuickDraw coordinates */
  160. void FlipCoords(Rect *RectP, int theFile)
  161. {
  162.     OutputString("1 -1 scale ", theFile);
  163.     OutputNum(0, theFile);
  164.     OutputNum(-RectP->bottom, theFile);
  165.     OutputString("translate ", theFile);
  166. }
  167.  
  168.  
  169. void WriteEpilogue(int theFile)
  170. {
  171.     register int i;
  172.     for (i=0;; i++) {
  173.         if (epilogueStrs[i][0] == 0)        /* finished? */
  174.             break;
  175.         OutputString(epilogueStrs[i], theFile);
  176.     }    
  177. }